package edu.ynu.se.xiecheng.achitectureclass.service;

import edu.ynu.se.xiecheng.achitectureclass.domain.Result;
import edu.ynu.se.xiecheng.achitectureclass.common.service.LogicService;
import edu.ynu.se.xiecheng.achitectureclass.dao.CustomerDao;
import edu.ynu.se.xiecheng.achitectureclass.dao.OrderDao;
import edu.ynu.se.xiecheng.achitectureclass.dao.ShopDao;
import edu.ynu.se.xiecheng.achitectureclass.domain.vo.LineItemVo;
import edu.ynu.se.xiecheng.achitectureclass.domain.vo.OrderVo;
import edu.ynu.se.xiecheng.achitectureclass.domain.entity.Customer;
import edu.ynu.se.xiecheng.achitectureclass.domain.entity.LineItem;
import edu.ynu.se.xiecheng.achitectureclass.domain.entity.Order;
import edu.ynu.se.xiecheng.achitectureclass.domain.entity.Shop;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CustomerService extends LogicService<CustomerDao, Customer, Long> {
    @Resource
    OrderDao orderDao;
    @Resource
    ShopDao shopDao;

    public CustomerService(CustomerDao lr) {
        super(lr);
    }

    @Transactional
    public Result addOrder(Long customerId, Long shopId, Double totalPrice, List<LineItem> list) {
        Customer customer = getDAO().findById(customerId).get();
        Order order = new Order();
        order.setCustomer(customer);
        Shop shop = shopDao.findById(shopId).get();
        List<LineItem> newList = new ArrayList<>();
        if (list != null) {
            for (int i = 0; i < list.size(); i++) {
                list.get(i).setOrder(order);
                newList.add(list.get(i));
            }
        }

        order.setLineItems(newList);
        order.setPayState(0);
        order.setState(0);
        order.setTotalPrice(totalPrice);
        order.setShop(shop);
        customer.addOrder(order);
        Customer save = getDAO().save(customer);

        if (save == null) {
            return new Result("保存失败");
        }
        return new Result(true, save.getOrders().get(save.getOrders().size() - 1));
    }

    @Transactional
    public Result payState(Long orderId) {
        Order orderById = orderDao.findOrderById(orderId);
        orderById.payOrder();
        return new Result(true, orderById);
    }

    public Result getOrder(Long customerId, Long shopId) {
        Shop shop = new Shop();
        shop.setId(shopId);
        Customer customer = new Customer();
        customer.setId(customerId);
        List<OrderVo> orderVos = new ArrayList<>();
        List<Order> res = orderDao.findOrderByShopAndAndCustomerAndPayState(shop, customer, 0);
        List<LineItemVo> lineItemVo = new ArrayList<>();
        for (int i = 0; i < res.size(); i++) {
            OrderVo orderVo = new OrderVo();
            for (int j = 0; j < res.get(i).getLineItems().size(); j++) {
                LineItemVo itemDto = new LineItemVo();
                itemDto.setItemName(res.get(i).getLineItems().get(j).getItem().getName());
                itemDto.setTotalPrice(res.get(i).getLineItems().get(j).getTotalPrice());
                itemDto.setCount(res.get(i).getLineItems().get(j).getCount());
                itemDto.setId(res.get(i).getLineItems().get(j).getId());

                lineItemVo.add(itemDto);
            }
            BeanUtils.copyProperties(res.get(i), orderVo);
            orderVo.setLineItemVo(lineItemVo);
            orderVos.add(orderVo);
        }
        if (res == null)
            return new Result("没有订单！");
        else
            return new Result(true, orderVos);
    }

    public Result getAllOrder(Long customerId) {
        Customer customer = new Customer();
        customer.setId(customerId);
        List<OrderVo> orderVos = new ArrayList<>();
        List<Order> res = orderDao.findOrderByCustomer(customer);
        List<LineItemVo> lineItemVo = new ArrayList<>();
        for (int i = 0; i < res.size(); i++) {
            OrderVo orderVo = new OrderVo();
            for (int j = 0; j < res.get(i).getLineItems().size(); j++) {
                LineItemVo itemDto = new LineItemVo();
                itemDto.setItemName(res.get(i).getLineItems().get(j).getItem().getName());
                itemDto.setTotalPrice(res.get(i).getLineItems().get(j).getTotalPrice());
                itemDto.setCount(res.get(i).getLineItems().get(j).getCount());
                itemDto.setId(res.get(i).getLineItems().get(j).getId());
                lineItemVo.add(itemDto);
            }

            BeanUtils.copyProperties(res.get(i), orderVo);
            orderVo.setLineItemVo(lineItemVo);
            orderVo.setShopName(res.get(i).getShop().getName());
            orderVos.add(orderVo);
        }
        if (res == null)
            return new Result("没有订单");
        else
            return new Result(true, orderVos);
    }

    public Result getOrderByPayState(Long customerId, Integer payState) {
        Customer customer = new Customer();
        customer.setId(customerId);
        List<OrderVo> orderVos = new ArrayList<>();
        List<Order> res = orderDao.findOrderByCustomerAndPayState(customer, payState);
        List<LineItemVo> lineItemVo = new ArrayList<>();
        for (int i = 0; i < res.size(); i++) {
            OrderVo orderVo = new OrderVo();
            for (int j = 0; j < res.get(i).getLineItems().size(); j++) {
                LineItemVo itemDto = new LineItemVo();
                itemDto.setItemName(res.get(i).getLineItems().get(j).getItem().getName());
                itemDto.setTotalPrice(res.get(i).getLineItems().get(j).getTotalPrice());
                itemDto.setCount(res.get(i).getLineItems().get(j).getCount());
                itemDto.setId(res.get(i).getLineItems().get(j).getId());
                lineItemVo.add(itemDto);
            }

            BeanUtils.copyProperties(res.get(i), orderVo);
            orderVo.setLineItemVo(lineItemVo);
            orderVo.setShopName(res.get(i).getShop().getName());
            orderVos.add(orderVo);
        }
        if (res == null)
            return new Result("无订单");
        else
            return new Result(true, orderVos);
    }

    public Result getOrderByState(Long customerId, Integer state, Integer payState) {
        Customer customer = new Customer();
        customer.setId(customerId);
        List<OrderVo> orderVos = new ArrayList<>();
        List<Order> res = orderDao.findOrderByCustomerAndStateAndPayState(customer, state, payState);
        List<LineItemVo> lineItemVo = new ArrayList<>();
        for (int i = 0; i < res.size(); i++) {
            OrderVo dto = new OrderVo();
            for (int j = 0; j < res.get(i).getLineItems().size(); j++) {
                LineItemVo itemDto = new LineItemVo();
                itemDto.setItemName(res.get(i).getLineItems().get(j).getItem().getName());
                itemDto.setTotalPrice(res.get(i).getLineItems().get(j).getTotalPrice());
                itemDto.setCount(res.get(i).getLineItems().get(j).getCount());
                itemDto.setId(res.get(i).getLineItems().get(j).getId());
                lineItemVo.add(itemDto);
            }

            BeanUtils.copyProperties(res.get(i), dto);
            dto.setLineItemVo(lineItemVo);
            dto.setShopName(res.get(i).getShop().getName());
            orderVos.add(dto);
        }
        if (res == null)
            return new Result("无订单");
        else
            return new Result(true, orderVos);
    }

    public Result getOrderById(Long orderId) {
        Order res = orderDao.findOrderById(orderId);

        List<LineItemVo> lineItemVo = res.getLineItems().stream()
                .map(lineItem -> {
                    LineItemVo itemDto = new LineItemVo();
                    itemDto.setItemName(lineItem.getItem().getName());
                    itemDto.setTotalPrice(lineItem.getTotalPrice());
                    itemDto.setCount(lineItem.getCount());
                    itemDto.setId(lineItem.getId());
                    return itemDto;
                })
                .collect(Collectors.toList());

        OrderVo dto = new OrderVo();
        BeanUtils.copyProperties(res, dto);
        dto.setLineItemVo(lineItemVo);
        dto.setShopName(res.getShop().getName());
        dto.setCustomerName(res.getCustomer().getName());

        return new Result(true, dto);
    }
}
